#include "../../config.h"

#include <glibmm/i18n.h>

#include "../application.h"
#include "../mainwindow.h"
#include "../processview.h"
#include "../misc.h"
#include "p_general.h"
#include "p_macros.h"

namespace gpyp {
namespace pref {

//========================
// General
void General::ss_on_provider_changed(ss::RefProvider provider) {
  using namespace boost;
  ss_.set_sensitive(provider);
  if (provider) {
    ss_provider_.set_label(format("(%s)", provider->get_name().c_str()));
    ss_provider_.show();
  } else {
    ss_provider_.hide();
  }
}

void General::sound_driver_on_changed() {
  Glib::ustring driver = sound_driver_.get_entry()->get_text();
  ConfMain::RefSound sound = app_.conf().sound();
  sound_alsa_ .hide();
  sound_pulse_.hide();
  sound_esd_  .hide();
  sound_oss_  .hide();
  if (driver == sound->alsa()->get_name()) {
    sound_alsa_.show();
  } else if (driver == sound->pulse()->get_name()) {
    sound_pulse_.show();
  } else if (driver == sound->esd()->get_name()) {
    sound_esd_.show();
  } else if (driver == sound->oss()->get_name()) {
    sound_oss_.show();
  }
}

#define GENERAL (app_.conf().general())
General::General(Application &app, Gtk::Window &/*parent*/) :
  Gtk::VBox            (false, 2),
  app_                 (app),
  run_peercast_        (_("Run peercast on startup")),
  run_pcraw_proxy_     (_("Run pcraw_proxy on startup")),
  enable_status_icon_  (_("Enable status icon")),
  avoid_close_         (_("Minimize to system tray on close window")),
  proc_detach_delay_   (1),
  ss_disable_auto_play_(_("Disable autoplay when screensaver is active")),
  ss_mute_             (_("Mute sounds when screensaver is active"))
{
  pack_start(run_peercast_, false, false);
  pack_start(run_pcraw_proxy_, false, false);
  pack_start(enable_status_icon_, false, false);
  Gtk::Alignment *a1 = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
  a1->set_padding(0, 0, 16, 0);
  a1->add(avoid_close_);
  pack_start(*a1, false, false);

  proc_detach_delay_.set_increments(1, 0);
  proc_detach_delay_.set_range(-1, 120);
  proc_detach_delay_.set_alignment(Gtk::ALIGN_RIGHT);
  Gtk::Table *t1 = Gtk::manage(new Gtk::Table());
  TABLE_LABEL_F(*t1, 0, 0, _("Statusbar"));
  TABLE_LABEL_F(*t1, 0, 1, _("Shell"));
  TABLE_LABEL_F(*t1, 2, 1, _("Escape chars"));
  TABLE_LABEL_F(*t1, 0, 2, _("Command prefix"));
  TABLE_LABEL_F(*t1, 0, 3, _("Detach process delay"));
  t1->attach(statusbar_format_,  1, 4, 0, 1);
  t1->attach(shell_,             1, 2, 1, 2);
  t1->attach(shell_esc_,         3, 4, 1, 2);
  t1->attach(command_prefix_,    1, 4, 2, 3);
  t1->attach(proc_detach_delay_, 1, 4, 3, 4);
  TABLE_SPACING(*t1, 2, 2);
  pack_start(*t1, false, false);

  Gtk::VBox *v1 = Gtk::manage(new Gtk::VBox(false, 2));
  v1->pack_start(ss_disable_auto_play_, false, true);
  v1->pack_start(ss_mute_,              false, true);
  v1->set_border_width(2);
  ss_.add(*v1);
  Gtk::HBox *h1 = Gtk::manage(new Gtk::HBox(false, 4));
  gtk_box_pack_start(GTK_BOX(h1->gobj()),
                     gtk_label_new(_("Screen saver")), FALSE, FALSE, 0);
  h1->pack_start(ss_provider_, false, false);
  ss_.set_label_widget(*h1);
  pack_start(ss_, false, false);

  sound_driver_.append_text("alsa");
  sound_driver_.append_text("pulse");
  sound_driver_.append_text("esd");
  sound_driver_.append_text("oss");

#define SOUND_ROW(P, N, R) {                                    \
    TABLE_LABEL(sound_##P##_, R, #N);                           \
    sound_##P##_.attach(sound_##P##_##N##_, 1, 2, R, (R) + 1);  \
  }
  SOUND_ROW(alsa,  card,     0);
  SOUND_ROW(alsa,  dev,      1);
  SOUND_ROW(alsa,  buf_size, 2);
  SOUND_ROW(pulse, server,   0);
  SOUND_ROW(pulse, sink,     1);
  SOUND_ROW(esd,   host,     0);
  SOUND_ROW(oss,   dsp,      0);
#undef SOUND_ROW
  TABLE_SPACING(sound_alsa_,  2, 2);
  TABLE_SPACING(sound_pulse_, 2, 2);
  TABLE_SPACING(sound_esd_,   2, 2);
  TABLE_SPACING(sound_oss_,   2, 2);
  Gtk::HBox *h2 = Gtk::manage(new Gtk::HBox(false, 2));
  h2->pack_start(*Gtk::manage(new Gtk::Label(_("Driver"))), false, false);
  h2->pack_start(sound_driver_, true, true);
  Gtk::VBox *v2 = Gtk::manage(new Gtk::VBox(false, 2));
  v2->pack_start(*h2,           false, false);
  v2->pack_start(sound_alsa_,   false, false);
  v2->pack_start(sound_pulse_,  false, false);
  v2->pack_start(sound_esd_,    false, false);
  v2->pack_start(sound_oss_,    false, false);
  v2->set_border_width(2);
  Gtk::Frame *f1 = Gtk::manage(new Gtk::Frame(_("Sound")));
  f1->add(*v2);
  pack_start(*f1, false, false);
  show_all();

  ConfMain::RefGeneral general = app_.conf().general();
  general->run_peercast()     ->attach(run_peercast_     .property_active());
  general->run_pcraw_proxy()  ->attach(run_pcraw_proxy_  .property_active());
  general->avoid_close()      ->attach(avoid_close_      .property_active());
  general->statusbar_format() ->attach(statusbar_format_ .property_text());
  general->shell()            ->attach(shell_            .property_text());
  general->shell_esc()        ->attach(shell_esc_        .property_text());
  general->command_prefix()   ->attach(command_prefix_   .property_text());

#ifdef DISABLE_STATUS_ICON
  enable_status_icon_.set_sensitive(false);
  avoid_close_.set_sensitive(false);
#else
  app_.mainwindow()->status_icon()->enable()->attach(enable_status_icon_.property_active());
  app_.mainwindow()->status_icon()->enable()->attach(avoid_close_.property_sensitive());
#endif

  app_.mainwindow()->panel()->processes()->detach_delay()->attach(proc_detach_delay_.property_value());

  ConfMain::RefScreenSaver ss = app_.conf().screensaver();
  ss->disable_auto_play()->attach(ss_disable_auto_play_.property_active());
  ss->mute()             ->attach(ss_mute_.property_active());

  ConfMain::RefSound sound = app_.conf().sound();
  sound->driver()->attach(sound_driver_.get_entry()->property_text());

  sound->alsa()->card()    ->attach(sound_alsa_card_    .property_text());
  sound->alsa()->dev()     ->attach(sound_alsa_dev_     .property_text());
  sound->alsa()->buf_size()->attach(sound_alsa_buf_size_.property_text());
  sound->pulse()->server() ->attach(sound_pulse_server_ .property_text());
  sound->pulse()->sink()   ->attach(sound_pulse_sink_   .property_text());
  sound->esd()->host()     ->attach(sound_esd_host_     .property_text());
  sound->oss()->dsp()      ->attach(sound_oss_dsp_      .property_text());

  sound_driver_on_changed();

  sound_alsa_ .set_no_show_all(true);
  sound_pulse_.set_no_show_all(true);
  sound_esd_  .set_no_show_all(true);
  sound_oss_  .set_no_show_all(true);
  sound_driver_on_changed();
  sound_driver_.get_entry()->property_text().signal_changed()
    .connect(sigc::mem_fun(*this, &General::sound_driver_on_changed));

  ss_on_provider_changed(ss::get_provider());
  conn_ss_provider_changed_ = ss::signal_provider_changed()
    .connect(sigc::mem_fun(*this, &General::ss_on_provider_changed));
}

}/*pref*/
}/*gpyp*/
